package com.chenggong.custom.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.text.TextUtils
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import com.chenggong.custom.R
import java.util.regex.Matcher
import java.util.regex.Pattern

/**
 * Created by chenggong on 18-5-2023.
 */
class MultilineTextView : AppCompatTextView {
    private var textHeight: Float = 0f
    private var multiline = 2

    private val linesList by lazy {
        arrayListOf<String>()
    }

    fun instructions(): String{
        return  "${MultilineTextView::class.java.name}\n\n" +
                "多行显示的TextView,超出指定行数显示省略号\n" +
                "默认显示两行\n" +
                "app:multiline=\"2\""
    }

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context,
        attrs,
        defStyleAttr){
        val typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MultilineTextView)
        multiline =
            typedArray.getInt(R.styleable.MultilineTextView_multiline, 2)
        typedArray.recycle()
    }

    override fun setText(text: CharSequence?, type: BufferType?) {
        if(width <= 0){
            super.setText(text, type)
            return
        }
        linesList.clear()
        if(!TextUtils.isEmpty(text?.toString()?.trim())){
            val content = replaceBlank(text)
            var mText: StringBuilder = StringBuilder()
            textHeight = paint.getFontMetrics(Paint.FontMetrics())
            val ellipsisWidth = paint.measureText("...")
            val textWidth = paint.measureText(content)
            val lineWidth = width - paddingLeft - paddingRight - 5 //误差5
            if(textWidth >= lineWidth){
                //内容超出两行
                if (content != null) {
                    for (chart in content){
                        val textWidth = paint.measureText(mText.toString())
                        val chartWidth = paint.measureText(chart.toString())
                        val currentWidth = if(linesList.size == multiline -1) textWidth + chartWidth + ellipsisWidth else textWidth + chartWidth
                        if(currentWidth > lineWidth ){
                            if(linesList.size < multiline -1){
                                linesList.add(mText.toString())
                                mText.clear()
                                mText.append(chart)
                            }else{
                                break
                            }
                        }else{
                            mText.append(chart)
                        }
                    }

                    mText.append("...")
                    linesList.add(mText.toString())
                    mText.clear()
                }
            }else{
                mText.append(content)
                mText.append("...")
                linesList.add(mText.toString())
                mText.clear()
            }
        }else{

        }
        invalidate()
        if(linesList.size == 0){
            super.setText(text, type)
        }else{
            super.setText(" ", type)
        }
    }

    override fun getText(): CharSequence? {
        if(linesList.size > 0){
            val string = StringBuilder()
            linesList.forEach {
                string.append(it)
            }
            return string.toString()
        }
        return super.getText()
    }

    private fun replaceBlank(src: CharSequence?): String? {
        var dest = ""
        if (src != null) {
            val pattern: Pattern = Pattern.compile("\t|\r|\n|")
            val matcher: Matcher = pattern.matcher(src)
            dest = matcher.replaceAll("")
        }
        return dest
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if(linesList == null)return
        for (i in 0 until linesList.size) {
            if(i == 0){
                canvas?.drawText(linesList[i], paddingLeft.toFloat(), textHeight + paddingTop , paint)
            }else{
                canvas?.drawText(linesList[i], paddingLeft.toFloat(), textHeight*(i+1) + paddingTop, paint)
            }
        }
    }

}